package com.hanvon.face;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.hanvon.faceRec.*;
import com.hanvon.faceRec.HWFaceLib.eExpDegreeRule;
import com.hanvon.faceRec.HWFaceLib.eExpressionRule;
import net.sunzc.hwfacetest.utils.AndroidCamera;
import net.sunzc.hwfacetest.utils.FileUtils;
import net.sunzc.hwfacetest.utils.MyLog;

import java.io.File;
import java.util.Arrays;
import java.util.List;

@SuppressLint("NewApi")
public class HanvonfaceShowView extends SurfaceView implements Camera.PreviewCallback {

    /* 设置需要像素的宽*高--后边注释参数为次Camera支持的参数 */
    private static int PIXEL_WIDTH = 640;// 1280,800,768,720,640,576,480,384,352
    private static int PIXEL_HEIGHT = 480;// 720,480,432,480,480,432,320,288,288
    private static int EXP_MAX = 4;
    private static int EXP_MIN = 2;
    private String TAG = "FaceRecCameraPreview";
    private AndroidCamera mCamera;
    private SurfaceHolder mSurfaceHolder02;// mSurfaceHolder
    // 相机Preview，mSurfaceHolder02
    // 显示框
    private SurfaceView mSurfaceView02;// mSurfaceHolder02 显示框 对应SurfaceView
    private boolean isMultiFace = false;
    private int intFaceNum = 1;
    private int numfarme = 0;
    private OUserInfo showUserInfo = null;
    private int[] hgffs = new int[1];
    private Context mContext;
    private IResultCallback mResultCallback = null; // 回调函数
    private int TEMPLATE_SIZE = 5;
    private int mRotation = 0; // 翻转角度
    private boolean mbInited = false;
    private eExpressionRule[] eExpression = new eExpressionRule[1];
    private eExpDegreeRule[] eDegreeRule = new eExpDegreeRule[1];

    /* 年龄性别 */
    private int nFrameNum = 0;
    private int nShowFrameNum = 0;
    private int nFemale = 0;
    private int nMale = 0;
    private int nSex = -1;
    private int nAgeLabel = -1, nAgeIdx, nAgeMax;
    private int nAgeValue = 0;
    private int[] pnResAge = new int[6];
    private int nResExactAge = 0;
    private int nFailLocNum = 0;

    private int Expcount = 0;
    private int Exp = -1;
    private int nExpState = -1;
    private int nSexState = -1;
    private String strNameState = "";

    public HanvonfaceShowView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        mContext = context;
    }

    public HanvonfaceShowView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        mContext = context;
    }

    /**
     * 设置显示和绘制SurfaceView
     *
     * @param view02 绘制 Surface
     */
    public void setSurfaceView(SurfaceView view02) {
        /* 以SurfaceView作为相机Preview之用mSurfaceView01显示相机mSurfaceView02显示脸框 */
        mSurfaceView02 = view02;
        mSurfaceView02.setZOrderOnTop(true);
        mSurfaceHolder02 = mSurfaceView02.getHolder();
        mSurfaceHolder02.setFormat(PixelFormat.TRANSLUCENT);
    }

    /**
     * 初始化SDK
     *
     * @param nImgWidth  图像宽度
     * @param nImgHeihgt 图像高度
     */
    public void onInitSDK(int nImgWidth, int nImgHeihgt) {
        PIXEL_WIDTH = nImgWidth;
        PIXEL_HEIGHT = nImgHeihgt;
        int result05;
        /***********************************************************/
        /***
         * 人脸检测接口描述 /***初始化函数 /
         ***********************************************************/
        Log.i(TAG, "scanCoachQRCode--InitFaceEngine");
        result05 = HWFaceLib.getInstance().InitFaceEngine(
                FaceCoreHelper.SERIAL_NUMBER);
        Log.i(TAG, "end--InitFaceEngine return:" + Integer.toString(result05));
        mbInited = true;
    }

    /**
     * 开启人脸检测
     */
    public void onStartPreview(int cameraId) {
        if (!mbInited) {
            onInitSDK(PIXEL_WIDTH, PIXEL_HEIGHT);
        }
        initCamera(cameraId);
        Camera.Parameters parameters = mCamera.getParameters();
        PIXEL_WIDTH = parameters.getPreviewSize().width;
        PIXEL_HEIGHT = parameters.getPreviewSize().height;
        showUserInfo = new OUserInfo();
        switch (mRotation) {
            case 0:
                showUserInfo.nHeight = PIXEL_HEIGHT;
                showUserInfo.nWidth = PIXEL_WIDTH;
                break;
            default:
                showUserInfo.nHeight = PIXEL_WIDTH;
                showUserInfo.nWidth = PIXEL_HEIGHT;
                break;
        }
        showUserInfo.nImgNum = TEMPLATE_SIZE;
        showUserInfo.pbImageArray = new byte[PIXEL_WIDTH * PIXEL_HEIGHT * 2 * TEMPLATE_SIZE];
        showUserInfo.pFacePos = new int[12 * 16];
    }

    /**
     * 释放SDK资源
     */
    public void onReleaseSDK() {
        mCamera.release();
        HWFaceLib.getInstance().ReleaseFaceEngine();
        showUserInfo.pbImageArray = null;
        mbInited = false;
    }

    private void initCamera(int cameraId) {
        mCamera = AndroidCamera.open(cameraId);
        // 非预览时and相机打开时，开启preview
        Log.i(TAG, "inside the camera");
            /* 创建Camera.Parameters对象 */
        Camera.Parameters parameters = mCamera.getParameters();
            /* 设置相片格式为JPEG */
        parameters.setPictureFormat(PixelFormat.JPEG);
        if (PIXEL_WIDTH != 0 && PIXEL_HEIGHT != 0) {
                /* 指定preview的屏幕大小 */
            parameters.setPreviewSize(PIXEL_WIDTH, PIXEL_HEIGHT);
                /* 设置图片分辨率大小 */
            parameters.setPictureSize(PIXEL_WIDTH, PIXEL_HEIGHT);
        }
        parameters.setPreviewFrameRate(15);
        parameters.setJpegQuality(95);
        List<String> list = parameters.getSupportedAntibanding();
        if (list != null) {
            for (String aList : list) {
                if (aList.equals(Camera.Parameters.ANTIBANDING_50HZ)) {
                    parameters
                            .setAntibanding(Camera.Parameters.ANTIBANDING_50HZ);
                }
            }
        }
        list = parameters.getSupportedWhiteBalance();
        if (list != null) {
            for (String aList : list) {
                if (aList.equals(Camera.Parameters.WHITE_BALANCE_AUTO)) {
                    parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
                }
            }
        }
        mCamera.setParameters(parameters);
        mCamera.setCameraPreviewOrientation(((Activity) getContext()).getWindowManager().getDefaultDisplay().getRotation());
        mCamera.preview(this, this);
    }

    /**
     * 设置回调函数
     *
     * @param callback
     */
    public void onRegisterResultCallback(IResultCallback callback) {
        this.mResultCallback = callback;
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        int heightf = mSurfaceHolder02.getSurfaceFrame().height();
        int widthf = mSurfaceHolder02.getSurfaceFrame().width();
        float hratio = (float) heightf / (float) PIXEL_HEIGHT;
        float wratio = (float) widthf / (float) PIXEL_WIDTH;
        switch (mRotation) {
            case 0:
                break;
            default:
                hratio = (float) heightf / (float) PIXEL_WIDTH;
                wratio = (float) widthf / (float) PIXEL_HEIGHT;
                break;
        }
        Canvas canvas = mSurfaceHolder02.lockCanvas(null);
        if (canvas == null)
            return;
        numfarme++;
        if ((numfarme % 5) == 0 && hgffs.length > 0) {
            int[] faceNum = new int[1];
            int[] pnSuggestion = new int[1];
            int[] nRule = new int[1];
            int[] nDisRule = new int[1];
            int[] nStrRule = new int[1];
            int[] pnAge = new int[intFaceNum * 2];
            int[] pnGender = new int[intFaceNum];
            if (isMultiFace) {
                if (intFaceNum < 2)
                    intFaceNum = 4;
                faceNum[0] = intFaceNum;
            } else {
                intFaceNum = 1;
                faceNum[0] = intFaceNum;
            }
            int[] facePosition = new int[intFaceNum * 12];
            int[] userID = new int[intFaceNum];
            int[] userFtrPos = new int[intFaceNum];
            int[] piRst = new int[1];
            int[] piScore = new int[1];

            int result = -1;
            int startX = 0;
            int startY = 0;
            int stopX = 0;
            int stopY = 0;

            int lefteyeX = 0;
            int lefteyeY = 0;
            int righteyeX = 0;
            int righteyeY = 0;

            long timeBegin;
            long timeEnd;

            int width = PIXEL_WIDTH;
            int height = PIXEL_HEIGHT;
            byte[] rotateData = new byte[data.length];

            switch (mRotation) {
                case 0:
                    width = PIXEL_WIDTH;
                    height = PIXEL_HEIGHT;
                    System.arraycopy(data, 0, rotateData, 0, data.length);
                    break;
                default:
                    width = PIXEL_HEIGHT;
                    height = PIXEL_WIDTH;
                    UtilFunc.rotateYuvData(rotateData, data, PIXEL_WIDTH,
                            PIXEL_HEIGHT, 1);
                    break;
            }

            /***********************************************************/
            /***
             * 人脸检测接口描述 /***人脸定位 /
             ***********************************************************/
            rotateData = FileUtils.fileToByteArray(new File("/sdcard/takePhotoRecImage"));
            result = HWFaceLib.getInstance().FaceDetection(rotateData, width, height, facePosition, intFaceNum, faceNum);
            Log.i(TAG, "人脸检测:\nrotateData" + rotateData.length +
                    "\nwidth:" + width +
                    "\nheight:" + height +
                    "\npnDetectFaceNum:" + faceNum[0] +
                    "\nfacePosition:" + Arrays.toString(facePosition));
            if (result == 0) {

                for (int i = 0; i < faceNum[0]; i++) {
                    timeBegin = System.nanoTime();
                    int[] pnID = new int[1];
                    int[] fs = new int[1];
                    int[] pnScore = new int[1];
                    int[] pnFtrPos = new int[1];
                    int[] tempfacePos = new int[12];
                    timeBegin = System.nanoTime();
                    System.arraycopy(facePosition, i * tempfacePos.length,
                            tempfacePos, 0, tempfacePos.length);
                    /***********************************************************/
                    /***
                     * 人脸检测接口描述 /***人脸比对 /****
                     *******************************************************/
                    FileUtils.writeFile("/sdcard/recImage", rotateData);
                    result = HWFaceLib.getInstance().FaceRecognition(rotateData, width,
                            height, tempfacePos, pnID, pnScore, pnFtrPos);
                    timeEnd = System.nanoTime();
                    long CompareFeaturtime = (timeEnd - timeBegin) / 1000000;

                    userID[i] = pnID[0];
                    if (pnID[0] < 0)
                        fs[0] = 0;
                    else {
                        /*if(fs[0] != 0)
                            fss = fs[0];*/
                    }
                    if (pnFtrPos[0] > -1)
                        userFtrPos[i] = pnFtrPos[0];
                }

            } else {
                canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
                mSurfaceHolder02.unlockCanvasAndPost(canvas);
                if (this.mResultCallback != null)
                    this.mResultCallback.resultCallback(4, null, "", -1, -1,
                            -1, -1, -1, "识别中...");
                return;
            }
            try {
                canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);

                Paint mPaintCenter = new Paint();
                mPaintCenter.setColor(Color.DKGRAY);// 画笔为绿色
                mPaintCenter.setStrokeWidth(1);// 设置画笔粗细

                /***********************************************************/
                /***人脸检测接口描述
                 /***绘制人脸区域及其贴出人脸
                 /***********************************************************/

                /*******  处理镜像，注释结束******/


                for (int i = 0; i < faceNum[0]; i++) {
                    if (mCamera.getCameraId() == CameraInfo.CAMERA_FACING_FRONT) {
                        facePosition[i * 12 + 1] = width - facePosition[i * 12 + 1];
                        facePosition[i * 12 + 5] = width - facePosition[i * 12 + 5];
                        facePosition[i * 12 + 7] = width - facePosition[i * 12 + 7];
                    }
                    FacePos facepos = HWFaceLib.getInstance().GetFacePos(facePosition, 0);
                    eExpression[0] = HWFaceLib.getInstance().getExpressionRule(piRst[0]);
                    eDegreeRule[0] = HWFaceLib.getInstance().getExpDegreeRule(piScore[0]);
                    startX = facepos.nCol - ((facepos.nWidth / 2));
                    startY = facepos.nRow - ((facepos.nHeight / 2));
                    stopX = facepos.nCol + ((facepos.nWidth / 2));
                    stopY = facepos.nRow + ((facepos.nHeight / 2));


                    if (startX == 0 && startY == 0 && stopX == 0 && stopY == 0) {
                        break;
                    } else {
                        //添加 比例换算
                        startX = (int) ((float) startX * wratio);
                        startY = (int) ((float) startY * hratio);
                        stopX = (int) ((float) stopX * wratio);
                        stopY = (int) ((float) stopY * hratio);

                        if (userID[i] > 0) {
                            int resultUinfo = HWFaceLib.getInstance().GetUserInfobyID(userID[i], showUserInfo);
                            MyLog.e(TAG, "获取用户信息:" + showUserInfo.toString());
                            if (showUserInfo.nImgNum > 0) {
                                if (userFtrPos[i] >= showUserInfo.nImgNum) userFtrPos[i] = 0;
                                if (userFtrPos[i] < 0) userFtrPos[i] = 0;
                                canvasDrawLine(canvas, startX, startY, stopX, stopY, lefteyeX, lefteyeY, righteyeX, righteyeY, showUserInfo, userFtrPos[i], userID[i]);
//
                            } else {
                                canvasDrawLine(canvas, startX, startY, stopX, stopY, lefteyeX, lefteyeY, righteyeX, righteyeY, showUserInfo, -1, -1);
                            }
                            this.mResultCallback.resultCallback(0, null,
                                    showUserInfo.strName, -1, -1, -1, -1, -1,
                                    "识别成功");
                            userID[i] = 0;
                        } else {
                            canvasDrawLine(canvas, startX, startY, stopX, stopY, lefteyeX, lefteyeY, righteyeX, righteyeY, showUserInfo, -2, -1);
                            this.mResultCallback.resultCallback(4, null,
                                    showUserInfo.strName, -1, -1, -1, -1, -1,
                                    "识别中...");
                        }
                    }
                }
            } catch (Exception e) {
            }
        }
        mSurfaceHolder02.unlockCanvasAndPost(canvas);
    }

    private void canvasDrawLine(Canvas canvas, int startX, int startY, int stopX, int stopY, int Leftx, int Lefty, int Rightx, int Righty, OUserInfo userInfo, int nFtrPos, int nUserID) {
        try {
            Paint mPaint = new Paint();
            mPaint.setColor(0xff00FFFF);// 画笔为绿色
            mPaint.setStrokeWidth(2);// 设置画笔粗细
            mPaint.setTextSize(50.0f);

            //canvas.drawLine(startX, startY, stopX, startY, mPaint);
            canvas.drawLine(startX, startY, startX + 30, startY, mPaint);
            canvas.drawLine(stopX - 30, startY, stopX, startY, mPaint);

            //canvas.drawLine(startX, startY, startX, stopY, mPaint);
            canvas.drawLine(startX, startY, startX, startY + 30, mPaint);
            canvas.drawLine(startX, stopY - 30, startX, stopY, mPaint);

            //canvas.drawLine(stopX, stopY, stopX, startY, mPaint);
            canvas.drawLine(stopX, stopY, stopX, stopY - 30, mPaint);
            canvas.drawLine(stopX, startY + 30, stopX, startY, mPaint);

            //canvas.drawLine(stopX, stopY, startX, stopY, mPaint);
            canvas.drawLine(stopX, stopY, stopX - 30, stopY, mPaint);
            canvas.drawLine(startX + 30, stopY, startX, stopY, mPaint);
        } catch (Exception e) {
        }
    }

}
